home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Tools / Win95 Secrets / SETUP.Z / WIN32WLK.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-19  |  35.6 KB  |  1,051 lines

  1. //==================================
  2. // WIN32WLK - Matt Pietrek 1995
  3. // FILE: WIN32WLK.C
  4. //==================================
  5. #include <windows.h>
  6. #include <stdio.h>
  7. #include <stddef.h>
  8. #include <string.h>
  9. #include <stdarg.h>
  10. #include <malloc.h>
  11. #include <tlhelp32.h>
  12. #pragma hdrstop
  13. #include "mbassert.h"
  14. #include "win32wlk.h"
  15. #include "module32.h"
  16. #include "procdb.h"
  17. #include "threaddb.h"
  18. #include "k32objs.h"
  19.  
  20. // Prototype the functions for this
  21. void Handle_WM_COMMAND(HWND hWndDlg, WPARAM wParam, LPARAM lParam);
  22. void Handle_WM_INITDIALOG(HWND hWndDlg);
  23. void Handle_WM_DELETEITEM(HWND hWndDlg, WPARAM wParam, LPARAM lParam);
  24. BOOL CALLBACK Win32WlkDlgProc(HWND, UINT, WPARAM, LPARAM);
  25. void RecordListboxLineTypeAndValue(HWND hWnd, DWORD type, DWORD value);
  26. BOOL RetrieveListboxLineTypeAndValue(HWND hWnd, DWORD *type, DWORD *value);
  27. void UpdateProcessList(void);
  28. void UpdateThreadList(void);
  29. void UpdateModuleList(void);
  30. void ShowProcessDetails( DWORD processID );
  31. void ShowHandleTableDetails( PHANDLE_TABLE pHndTbl );
  32. void ShowThreadDetails( DWORD threadID );
  33. void ShowTIBDetails( PTIB ptib );
  34. void ShowModuleDetails( PIMTE pimte );
  35. void ShowPEHeader( PIMAGE_NT_HEADERS pNTHdr );
  36. void ShowMODREFListDetails( PMODREF pModRef );
  37. void lbprintf(HWND hWnd, char * format, ...);
  38. BOOL IsModule(PIMTE pimte);
  39. BOOL IsProcessId( DWORD pid);
  40. BOOL IsThreadId( DWORD tid);
  41. BOOL IsMODREF( PMODREF pModRef );
  42. PPROCESS_DATABASE PIDToPDB( DWORD pid );
  43. PTHREAD_DATABASE TIDToTDB( DWORD tid );
  44. void InitUnobsfucator(void);
  45. void InitModuleTableBase(void);
  46. void InitKernel32HeapHandle(void);
  47. void GetProcessNameFromHTask( HTASK hTask, PSTR szBuffer );
  48. void GetModuleNameFromIMTEIndex( unsigned short index, PSTR pszBuffer );
  49. PSTR GetKernel32ObjectType( PVOID pObject );
  50.  
  51. // HWNDs of the commonly used dialog controls
  52. HWND HWndMainList;
  53. HWND HWndDetails;
  54. HWND HWndDetailsDescription;
  55.  
  56. DWORD Unobsfucator = 0;
  57. PIMTE *PModuleTable = 0;
  58. HANDLE HKernel32Heap;
  59. BOOL fDebugVersion;
  60.  
  61. int PASCAL WinMain( HANDLE hInstance, HANDLE hPrevInstance,
  62.                     LPSTR lpszCmdLine, int nCmdShow )
  63. {
  64.     DialogBox(hInstance, "Win32WlkDlg", 0, (DLGPROC)Win32WlkDlgProc);
  65.     return 0;
  66. }
  67.  
  68. void UpdateProcessList(void)
  69. {
  70.     HANDLE hSnapshot;
  71.     
  72.     SendMessage(HWndMainList, LB_RESETCONTENT, 0, 0);
  73.  
  74.     hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPALL, 0 );
  75.     if ( hSnapshot )
  76.     {
  77.         PROCESSENTRY32 process;
  78.         BOOL fMore;
  79.  
  80.         process.dwSize = sizeof(process);
  81.         fMore = Process32First( hSnapshot, &process );
  82.         
  83.         while ( fMore )
  84.         {
  85.             PPROCESS_DATABASE ppdb;
  86.             char szBuffer[20];
  87.             
  88.             ppdb = PIDToPDB( process.th32ProcessID );
  89.             GetProcessNameFromHTask( ppdb->W16TDB, szBuffer );
  90.                 
  91.             lbprintf(HWndMainList, "%08X %s", process.th32ProcessID, szBuffer);
  92.             RecordListboxLineTypeAndValue( HWndMainList, LB_ITEM_PROCESS, 
  93.                                             process.th32ProcessID );
  94.             
  95.             fMore = Process32Next( hSnapshot, &process );
  96.         }
  97.         
  98.         CloseHandle( hSnapshot );
  99.     }
  100.  
  101.     // Set selection to first process in list, and show its details
  102.     SendMessage( HWndMainList, LB_SETCURSEL, 0, 0 );
  103.     PostMessage( GetParent(HWndMainList), WM_COMMAND,
  104.                     MAKEWPARAM(IDC_LB_MAIN_LIST, LBN_SELCHANGE),
  105.                     (LPARAM)HWndMainList );
  106. }
  107.  
  108. void UpdateThreadList(void)
  109. {
  110.     HANDLE hSnapshot;
  111.     
  112.     SendMessage(HWndMainList, LB_RESETCONTENT, 0, 0);
  113.  
  114.     hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPALL, 0 );
  115.     if ( hSnapshot )
  116.     {
  117.         THREADENTRY32 thread;
  118.         BOOL fMore;
  119.         
  120.         thread.dwSize = sizeof(thread);
  121.         fMore = Thread32First( hSnapshot, &thread );
  122.         
  123.         while ( fMore )
  124.         {
  125.             PPROCESS_DATABASE ppdb;
  126.             char szBuffer[20];
  127.             
  128.             ppdb = PIDToPDB( thread.th32OwnerProcessID );
  129.             GetProcessNameFromHTask( ppdb->W16TDB, szBuffer );
  130.                 
  131.             lbprintf( HWndMainList, "%08X %s", thread.th32ThreadID, szBuffer );
  132.             RecordListboxLineTypeAndValue( HWndMainList, LB_ITEM_PROCESS, 
  133.                                             thread.th32ThreadID );
  134.             
  135.             fMore = Thread32Next( hSnapshot, &thread );
  136.         }
  137.         
  138.         CloseHandle( hSnapshot );
  139.     }
  140.  
  141.     // Set selection to first thread in list, and show its details
  142.     SendMessage( HWndMainList, LB_SETCURSEL, 0, 0 );
  143.     PostMessage( GetParent(HWndMainList), WM_COMMAND,
  144.                     MAKEWPARAM(IDC_LB_MAIN_LIST, LBN_SELCHANGE),
  145.                     (LPARAM)HWndMainList );
  146. }
  147.  
  148. void UpdateModuleList(void)
  149. {
  150.     unsigned i, cIMTEs;
  151.     
  152.     InitModuleTableBase();      // In case PModuleTableArray got reallocated
  153.     
  154.     SendMessage(HWndMainList, LB_RESETCONTENT, 0, 0);
  155.  
  156.     cIMTEs = HeapSize( HKernel32Heap, 0, (PVOID)PModuleTable ) / sizeof(PIMTE);
  157.     
  158.     for( i=0; i < cIMTEs; i++ )
  159.     {
  160.         if ( PModuleTable[i] )
  161.         {
  162.             lbprintf( HWndMainList, "%s", PModuleTable[i]->pszModName );
  163.             RecordListboxLineTypeAndValue( HWndMainList, LB_ITEM_HMODULE, 
  164.                                             (DWORD)PModuleTable[i] );
  165.         }
  166.     }
  167.     
  168.     // Set selection to first module in list, and show its details
  169.     SendMessage( HWndMainList, LB_SETCURSEL, 0, 0 );
  170.     PostMessage( GetParent(HWndMainList), WM_COMMAND,
  171.                     MAKEWPARAM(IDC_LB_MAIN_LIST, LBN_SELCHANGE),
  172.                     (LPARAM)HWndMainList );
  173. }
  174.  
  175. DWORD_FLAGS ProcessFlagNames[] = 
  176. {
  177. { 0x00000001, "fDebugSingle" },
  178. { 0x00000002, "fCreateProcessEvent" },
  179. { 0x00000004, "fExitProcessEvent" },
  180. { 0x00000008, "fWin16Process" },
  181. { 0x00000010, "fDosProcess" },
  182. { 0x00000020, "fConsoleProcess" },
  183. { 0x00000040, "fFileApisAreOem" },
  184. { 0x00000080, "fNukeProcess" },
  185. { 0x00000100, "fServiceProcess" },
  186. { 0x00000800, "fLoginScriptHack" },
  187. { 0x00200000, "fSendDLLNotifications" },
  188. { 0x00400000, "fDebugEventPending" },
  189. { 0x00800000, "fNearlyTerminating" },
  190. { 0x08000000, "fFaulted" },
  191. { 0x10000000, "fTerminating" },
  192. { 0x20000000, "fTerminated" },
  193. { 0x40000000, "fInitError" },
  194. { 0x80000000, "fSignaled" },
  195. };
  196.  
  197. void ShowProcessDetails( DWORD pid )
  198. {
  199.     char szBuffer[512];
  200.     char szBuffer2[384];
  201.     PPROCESS_DATABASE ppdb;
  202.     PENVIRONMENT_DATABASE pedb;
  203.     unsigned i;
  204.     
  205.     if ( !IsProcessId(pid) )
  206.     {
  207.         MessageBox( 0, "Not a valid process", 0, MB_OK );
  208.         return;
  209.     }
  210.     
  211.     ppdb = PIDToPDB(pid);
  212.     pedb = ppdb->pEDB;
  213.     MBassert( IsK32HeapHandle(ppdb->pEDB) || !ppdb->pEDB);
  214.  
  215.     GetProcessNameFromHTask( (HTASK)ppdb->W16TDB, szBuffer2 );
  216.  
  217.     InitModuleTableBase();      // In case PModuleTableArray got reallocated
  218.     
  219.     wsprintf(szBuffer, "Process: %08X (%08X) %s", pid, ppdb, szBuffer2 );
  220.     SendMessage( HWndDetailsDescription, WM_SETTEXT, 0, (LPARAM)szBuffer );
  221.     SendMessage(HWndDetails, LB_RESETCONTENT, 0, 0);
  222.  
  223.     SendMessage( HWndDetails, WM_SETREDRAW, FALSE, 0 ); // Turn off redraws
  224.  
  225.     lbprintf( HWndDetails, "Type: %08X", ppdb->Type );
  226.     lbprintf( HWndDetails, "cReference: %08X", ppdb->cReference );
  227.     MBassert( !ppdb->un1 );
  228.  
  229.     lbprintf( HWndDetails, "someEvent: %08X", ppdb->someEvent );
  230.     MBassert( IsK32HeapHandle(ppdb->someEvent) || !ppdb->someEvent );
  231.  
  232.     lbprintf( HWndDetails, "TerminationStatus: %08X", ppdb->TerminationStatus );
  233.     MBassert( !ppdb->un2 );
  234.  
  235.     lbprintf( HWndDetails, "DefaultHeap: %08X", ppdb->DefaultHeap );
  236.     MBassert( IsHeapStart(ppdb->DefaultHeap) ) ;
  237.     lbprintf( HWndDetails, "MemoryContext: %08X", ppdb->MemoryContext );
  238.  
  239.     MBassert( IsRing0HeapHandle(ppdb->MemoryContext) );
  240.  
  241.     wsprintf(szBuffer, "flags: %08X ", ppdb->flags );
  242.     for ( i=0; i < (sizeof(ProcessFlagNames)/sizeof(DWORD_FLAGS)); i++ )
  243.         if ( ppdb->flags & ProcessFlagNames[i].value )
  244.             wsprintf(szBuffer + lstrlen(szBuffer), "%s ",
  245.                      ProcessFlagNames[i].name);
  246.     lbprintf( HWndDetails, szBuffer );
  247.  
  248.     lbprintf( HWndDetails, "pPSP: %08X", ppdb->pPSP );
  249.     lbprintf( HWndDetails, "PSPSelector: %04X", ppdb->PSPSelector );
  250.     MBassert( IsSelector( ppdb->PSPSelector ) );
  251.  
  252.     lbprintf( HWndDetails, "+MTE Index: %04X", ppdb->MTEIndex );
  253.     RecordListboxLineTypeAndValue( HWndDetails, LB_ITEM_HMODULE,
  254.                                     (DWORD)PModuleTable[ppdb->MTEIndex] );
  255.     lbprintf( HWndDetails, "cThreads: %04X", ppdb->cThreads );
  256.     MBassert( ppdb->cThreads );
  257.  
  258.     lbprintf( HWndDetails, "cNotTermThreads: %04X", ppdb->cNotTermThreads );
  259.     MBassert( !ppdb->un3 );
  260.  
  261.     lbprintf( HWndDetails, "cRing0Threads: %08X", ppdb->cRing0Threads );
  262.     MBassert( ppdb->cRing0Threads >= ppdb->cThreads );
  263.  
  264.     lbprintf( HWndDetails, "HeapHandle: %08X", ppdb->HeapHandle );
  265.     MBassert( IsHeapStart(ppdb->HeapHandle) ) ;
  266.     lbprintf( HWndDetails, "W16TDB: %08X", ppdb->W16TDB );
  267.  
  268.     MBassert( Is16BitGlobalHandle(ppdb->W16TDB) );
  269.  
  270.     lbprintf( HWndDetails, "MemMapFiles: %08X", ppdb->MemMapFiles );
  271.     MBassert( IsK32HeapHandle(ppdb->MemMapFiles) || !ppdb->MemMapFiles );
  272.  
  273.     lbprintf( HWndDetails, "pEDB: %08X", ppdb->pEDB );
  274.     lbprintf( HWndDetails, "+pHandleTable: %08X", ppdb->pHandleTable );
  275.     RecordListboxLineTypeAndValue( HWndDetails, LB_ITEM_HANDLE_TABLE,
  276.                                     (DWORD)ppdb->pHandleTable );
  277.     MBassert( IsK32HeapHandle(ppdb->pHandleTable) );
  278.  
  279.     lbprintf( HWndDetails, "+Parent process: %08X", ppdb->ParentPDB );
  280.     RecordListboxLineTypeAndValue( HWndDetails, LB_ITEM_PROCESS,
  281.                                     (DWORD)PIDToPDB((DWORD)ppdb->ParentPDB));
  282.     MBassert( IsK32HeapHandle( ppdb->ParentPDB ) || !ppdb->ParentPDB );
  283.  
  284.     lbprintf( HWndDetails, "+MODREFlist: %08X", ppdb->MODREFlist );
  285.     RecordListboxLineTypeAndValue( HWndDetails, LB_ITEM_MODREF_LIST,
  286.                                     (DWORD)ppdb->MODREFlist );
  287.     MBassert( IsK32HeapHandle( ppdb->MODREFlist ) );
  288.  
  289.     lbprintf( HWndDetails, "ThreadList: %08X", ppdb->ThreadList );
  290.     MBassert( IsK32HeapHandle(ppdb->ThreadList) );
  291.  
  292.     lbprintf( HWndDetails, "DebuggeeCB: %08X", ppdb->DebuggeeCB );
  293.     lbprintf( HWndDetails, "LocalHeapFreeHead: %08X", ppdb->LocalHeapFreeHead );
  294.     MBassert( IsDivisibleBy4(ppdb->LocalHeapFreeHead)
  295.               || !ppdb->LocalHeapFreeHead );
  296.  
  297.     lbprintf( HWndDetails, "InitialRing0ID: %08X", ppdb->InitialRing0ID );
  298.  
  299.     MBassert( !ppdb->un4[0] );
  300.     MBassert( !ppdb->un4[1] );
  301.     MBassert( !ppdb->un4[2] );
  302.  
  303.     if ( !fDebugVersion )
  304.         ppdb = (PPROCESS_DATABASE)( (PBYTE)ppdb - 4 );
  305.             
  306.     lbprintf( HWndDetails, "pConsole: %08X", ppdb->pConsole );
  307.     MBassert( IsK32HeapHandle(ppdb->pConsole) || !ppdb->pConsole );
  308.  
  309.     lbprintf( HWndDetails, "tlsInUseBits1: %08X", ppdb->tlsInUseBits1 );
  310.     lbprintf( HWndDetails, "tlsInUseBits2: %08X", ppdb->tlsInUseBits2 );
  311.     lbprintf( HWndDetails, "ProcessDWORD: %08X", ppdb->ProcessDWORD );
  312.     lbprintf( HWndDetails, "+ProcessGroup: %08X", ppdb->ProcessGroup );
  313.     RecordListboxLineTypeAndValue( HWndDetails, LB_ITEM_PROCESS,
  314.                                     (DWORD)PIDToPDB((DWORD)ppdb->ProcessGroup));
  315.     MBassert( IsK32HeapHandle( ppdb->ProcessGroup ) || !ppdb->ProcessGroup );
  316.  
  317.     lbprintf( HWndDetails, "pExeMODREF: %08X", ppdb->pExeMODREF );  
  318.     MBassert( IsK32HeapHandle( ppdb->pExeMODREF ) );
  319.  
  320.     lbprintf( HWndDetails, "TopExcFilter: %08X", ppdb->TopExcFilter );
  321.     lbprintf( HWndDetails, "BasePriority: %08X", ppdb->BasePriority );
  322.     MBassert( (ppdb->BasePriority <= 31) );
  323.  
  324.     lbprintf( HWndDetails, "HeapOwnList: %08X", ppdb->HeapOwnList );
  325.     MBassert( IsHeapStart(ppdb->HeapOwnList) );
  326.  
  327.     lbprintf( HWndDetails, "HeapHandleBlockList: %08X", ppdb->HeapHandleBlockList );
  328.     MBassert( IsDivisibleBy4(ppdb->HeapHandleBlockList)
  329.               || !ppdb->HeapHandleBlockList );
  330.  
  331.     lbprintf( HWndDetails, "pSomeHeapPtr: %08X", ppdb->pSomeHeapPtr );
  332.     MBassert( IsK32HeapHandle(ppdb->pSomeHeapPtr) || !ppdb->pSomeHeapPtr );
  333.  
  334.     lbprintf( HWndDetails, "pConsoleProvider: %08X", ppdb->pConsoleProvider );
  335.     MBassert( IsK32HeapHandle(ppdb->pConsoleProvider) ||
  336.               !ppdb->pConsoleProvider );
  337.  
  338.     lbprintf( HWndDetails, "EnvironSelector: %04X", ppdb->EnvironSelector );
  339.     MBassert( IsSelector( ppdb->EnvironSelector) || !ppdb->EnvironSelector );
  340.  
  341.     lbprintf( HWndDetails, "ErrorMode: %04X", ppdb->ErrorMode );
  342.     lbprintf( HWndDetails, "pevtLoadFinished: %08X", ppdb->pevtLoadFinished );
  343.     MBassert( IsK32HeapHandle(ppdb->pevtLoadFinished) );
  344.  
  345.     lbprintf( HWndDetails, "UTState: %04X", ppdb->UTState );
  346.  
  347.     SendMessage( HWndDetails, WM_SETREDRAW, TRUE, 0 );  // Turn on redraws
  348.         
  349.     if ( IsBadReadPtr(pedb, sizeof(ENVIRONMENT_DATABASE)) )
  350.         lbprintf( HWndDetails, "Environment Database ptr invalid" );
  351.     else
  352.     {
  353.     lbprintf( HWndDetails, "Environment Database:" );
  354.     __try
  355.     {
  356.         lbprintf(HWndDetails, "  pszEnvironment: %08X", pedb->pszEnvironment);
  357.         lbprintf(HWndDetails, "  pszCmdLine: %s", pedb->pszCmdLine);
  358.     }
  359.     __except( 1 ){}
  360.     lbprintf( HWndDetails, "  pszCurrDirectory: %s", pedb->pszCurrDirectory );
  361.     lbprintf( HWndDetails, "  pStartupInfo: %08X", pedb->pStartupInfo );
  362.     lbprintf( HWndDetails, "  hStdIn: %08X", pedb->hStdIn );
  363.     lbprintf( HWndDetails, "  hStdOut: %08X", pedb->hStdOut );
  364.     lbprintf( HWndDetails, "  hStdErr: %08X", pedb->hStdErr );
  365.     lbprintf( HWndDetails, "  un2: %08X", pedb->un2 );
  366.     lbprintf( HWndDetails, "  InheritConsole: %08X", pedb->InheritConsole );
  367.     lbprintf( HWndDetails, "  BreakType: %08X", pedb->BreakType );
  368.     lbprintf( HWndDetails, "  BreakSem: %08X", pedb->BreakSem );
  369.     lbprintf( HWndDetails, "  BreakEvent: %08X", pedb->BreakEvent );
  370.     lbprintf( HWndDetails, "  BreakThreadID: %08X", pedb->BreakThreadID );
  371.     lbprintf( HWndDetails, "  BreakHandlers: %08X", pedb->BreakHandlers );
  372.     }
  373.  
  374.     __try
  375.     {
  376.         MBassert( !pedb->un1 );
  377.     }
  378.     __except( 1 ){}
  379. }
  380.  
  381. void ShowHandleTableDetails( PHANDLE_TABLE pHndTbl )
  382. {
  383.     char szBuffer[384];
  384.     unsigned i;
  385.  
  386.     if ( IsBadReadPtr(pHndTbl, sizeof(HANDLE_TABLE)) || !pHndTbl->cEntries )
  387.     {
  388.         MessageBox( 0, "Not a valid handle table", 0, MB_OK );
  389.         return;
  390.     }
  391.  
  392.     wsprintf(szBuffer, "Handle Table: %08X", pHndTbl);
  393.     SendMessage( HWndDetailsDescription, WM_SETTEXT, 0, (LPARAM)szBuffer );
  394.     SendMessage(HWndDetails, LB_RESETCONTENT, 0, 0);
  395.  
  396.     SendMessage( HWndDetails, WM_SETREDRAW, FALSE, 0 ); // Turn off redraws
  397.     for ( i=0; i < pHndTbl->cEntries; i++ )
  398.     {
  399.         if ( !pHndTbl->array[i].pObject )
  400.             continue;
  401.         
  402.         lbprintf( HWndDetails, "%02X %08X %s", i, pHndTbl->array[i].pObject,
  403.                     GetKernel32ObjectType(pHndTbl->array[i].pObject) );
  404.     }
  405.  
  406.     SendMessage( HWndDetails, WM_SETREDRAW, TRUE, 0 );  // Turn on redraws
  407. }
  408.  
  409. DWORD_FLAGS TIBFlagNames[] = 
  410. {
  411. { 0x00000001, "TIBF_WIN32" },
  412. { 0x00000002, "TIBF_TRAP" },
  413. };
  414.  
  415. DWORD_FLAGS TDBFlagNames[] =
  416. {
  417. { 0x00000001, "fCreateThreadEvent" },
  418. { 0x00000002, "fCancelExceptionAbort" },
  419. { 0x00000004, "fOnTempStack" },
  420. { 0x00000008, "fGrowableStack" },
  421. { 0x00000010, "fDelaySingleStep" },
  422. { 0x00000020, "fOpenExeAsImmovableFile" },
  423. { 0x00000040, "fCreateSuspended" },
  424. { 0x00000080, "fStackOverflow" },
  425. { 0x00000100, "fNestedCleanAPCs" },
  426. { 0x00000200, "fWasOemNowAnsi" },
  427. { 0x00000400, "fOKToSetThreadOem" },
  428. };
  429.  
  430. void ShowThreadDetails( DWORD tid )
  431. {
  432.     char szBuffer[512];
  433.     char szBuffer2[20];
  434.     PTHREAD_DATABASE ptdb;
  435.     unsigned i;
  436.     
  437.     if ( !IsThreadId(tid) )
  438.     {
  439.         MessageBox( 0, "Not a valid thread", 0, MB_OK );
  440.         return;
  441.     }
  442.     
  443.     ptdb = TIDToTDB(tid);
  444.     
  445.     GetProcessNameFromHTask( (HTASK)ptdb->W16TDB, szBuffer2 );
  446.     
  447.     wsprintf(szBuffer, "Thread: %08X (%08X) %s", tid, ptdb, szBuffer2 );
  448.     SendMessage( HWndDetailsDescription, WM_SETTEXT, 0, (LPARAM)szBuffer );
  449.     SendMessage(HWndDetails, LB_RESETCONTENT, 0, 0);
  450.  
  451.     SendMessage( HWndDetails, WM_SETREDRAW, FALSE, 0 ); // Turn off redraws
  452.  
  453.     lbprintf(HWndDetails, "+pProcess: %08X", ptdb->pProcess);
  454.     RecordListboxLineTypeAndValue( HWndDetails, LB_ITEM_PROCESS, 
  455.                                     (DWORD)PIDToPDB((DWORD)ptdb->pProcess) );
  456.     lbprintf(HWndDetails, "+pProcess2: %08X", ptdb->pProcess2);
  457.     RecordListboxLineTypeAndValue( HWndDetails, LB_ITEM_PROCESS, 
  458.                                     (DWORD)PIDToPDB((DWORD)ptdb->pProcess2) );
  459.     lbprintf(HWndDetails, "pCurrentPriority: %08X (%X)",
  460.                 ptdb->pCurrentPriority, *(ptdb->pCurrentPriority) );
  461.     lbprintf(HWndDetails, "DeltaPriority: %08X", ptdb->DeltaPriority);
  462.     lbprintf(HWndDetails, "TopOfStack: %08X  (size:%X)",
  463.         ptdb->TopOfStack,
  464.         ptdb->TopOfStack -(ptdb->StackBase ? ptdb->StackBase:ptdb->TopOfStack));
  465.     lbprintf(HWndDetails, "StackLow: %08X (used:%X)", ptdb->StackLow,
  466.         ptdb->TopOfStack - ptdb->StackLow);
  467.     lbprintf(HWndDetails, "StackBase: %08X", ptdb->StackBase);
  468.     lbprintf(HWndDetails, "StackSelector16: %04X", ptdb->StackSelector16);
  469.     lbprintf(HWndDetails, "ThunkSS16: %04X", ptdb->ThunkSS16);
  470.     lbprintf(HWndDetails, "CurrentSS: %08X", ptdb->CurrentSS);
  471.     lbprintf(HWndDetails, "NegStackBase: %08X", ptdb->NegStackBase);
  472.     lbprintf(HWndDetails, "SSTable: %08X", ptdb->SSTable);
  473.     lbprintf(HWndDetails, "+pTIB: %08X", ptdb->pTIB);
  474.     RecordListboxLineTypeAndValue( HWndDetails, LB_ITEM_TIB,(DWORD)ptdb->pTIB);
  475.     lbprintf(HWndDetails, "TIBSelector: %04X", ptdb->TIBSelector);
  476.  
  477.     wsprintf(szBuffer, "TIBFlags: %08X ", ptdb->TIBFlags );
  478.     for ( i=0; i < (sizeof(TIBFlagNames)/sizeof(DWORD_FLAGS)); i++ )
  479.         if ( ptdb->TIBFlags & TIBFlagNames[i].value )
  480.             wsprintf(szBuffer + lstrlen(szBuffer), "%s ",
  481.                      TIBFlagNames[i].name);
  482.     lbprintf( HWndDetails, szBuffer );
  483.  
  484.     lbprintf(HWndDetails, "W16TDB: %04X", ptdb->W16TDB);
  485.     lbprintf(HWndDetails, "MessageQueue: %04X", ptdb->MessageQueue);
  486.     lbprintf(HWndDetails, "GetLastErrorCode: %08X", ptdb->GetLastErrorCode);
  487.     lbprintf(HWndDetails, "Win16MutexCount: %04X", ptdb->Win16MutexCount);
  488.     lbprintf(HWndDetails, "pvExcept: %08X", ptdb->pvExcept);
  489.  
  490.     wsprintf(szBuffer, "Flags: %08X ", ptdb->Flags );
  491.     for ( i=0; i < (sizeof(TDBFlagNames)/sizeof(DWORD_FLAGS)); i++ )
  492.         if ( ptdb->Flags & TDBFlagNames[i].value )
  493.             wsprintf(szBuffer + lstrlen(szBuffer), "%s ",
  494.                      TDBFlagNames[i].name);
  495.     lbprintf( HWndDetails, szBuffer );
  496.  
  497.     lbprintf(HWndDetails, "WaitNodeList: %08X", ptdb->WaitNodeList);
  498.     lbprintf(HWndDetails, "Ring0Thread: %08X", ptdb->Ring0Thread);
  499.     lbprintf(HWndDetails, "pTDBX: %08X", ptdb->pTDBX);
  500.     lbprintf(HWndDetails, "TerminationStatus: %08X", ptdb->TerminationStatus);
  501.     lbprintf(HWndDetails, "TerminationStack: %08X", ptdb->TerminationStack);
  502.     lbprintf(HWndDetails, "ThreadContext: %08X", ptdb->ThreadContext);
  503.     lbprintf(HWndDetails, "DebugContext: %08X", ptdb->DebugContext);
  504.     lbprintf(HWndDetails, "DebuggerCB: %08X", ptdb->DebuggerCB);
  505.     lbprintf(HWndDetails, "DebuggerThread: %08X", ptdb->DebuggerThread);
  506.  
  507.     // Relatively uninteresting fields
  508.     lbprintf(HWndDetails, "Type: %08X", ptdb->Type);
  509.     lbprintf(HWndDetails, "cReference: %08X", ptdb->cReference);
  510.     lbprintf(HWndDetails, "someEvent: %08X", ptdb->someEvent);
  511.     lbprintf(HWndDetails, "pTLSArray: %08X", ptdb->pTLSArray);
  512.     MBassert( ((DWORD)ptdb + offsetof(THREAD_DATABASE, TLSArray))
  513.                 == ptdb->pTLSArray);
  514.  
  515.     lbprintf(HWndDetails, "EmulatorSelector: %04X", ptdb->EmulatorSelector);
  516.     lbprintf(HWndDetails, "EmulatorData: %08X", ptdb->EmulatorData);
  517.     lbprintf(HWndDetails, "SelmanList: %08X", ptdb->SelmanList);
  518.     lbprintf(HWndDetails, "un4: %08X", ptdb->un4);
  519.  
  520.     MBassert( !ptdb->UserPointer );
  521.     MBassert( !ptdb->cHandles );
  522.     MBassert( !ptdb->Except16List );
  523.     MBassert( !ptdb->ThunkConnect );
  524.  
  525.     if ( fDebugVersion )
  526.     {
  527.         MBassert( !ptdb->un5[0] );
  528.         MBassert( !ptdb->un5[1] );
  529.         MBassert( !ptdb->un5[2] );
  530.         MBassert( !ptdb->un5[3] );
  531.         MBassert( !ptdb->un5[4] );
  532.         MBassert( !ptdb->un5[5] );
  533.         MBassert( !ptdb->un5[6] );
  534.         MBassert( !ptdb->pCreateData16 );
  535.         lbprintf(HWndDetails, "APISuspendCount: %08X", ptdb->APISuspendCount);
  536.         MBassert( !ptdb->un6 );
  537.         lbprintf(HWndDetails, "WOWChain: %08X", ptdb->WOWChain);
  538.         lbprintf(HWndDetails, "wSSBig: %08X", ptdb->wSSBig);
  539.         MBassert( !ptdb->un7 );
  540.         MBassert( !ptdb->lp16SwitchRec );
  541.         MBassert( !ptdb->un8[0] );
  542.         MBassert( !ptdb->un8[1] );
  543.         MBassert( !ptdb->un8[2] );
  544.         MBassert( !ptdb->un8[3] );
  545.         MBassert( !ptdb->un8[4] );
  546.         MBassert( !ptdb->un8[5] );
  547.         lbprintf(HWndDetails, "pSomeCritSect1: %08X", ptdb->pSomeCritSect1);
  548.         lbprintf(HWndDetails, "pWin16Mutex: %08X", ptdb->pWin16Mutex);
  549.         lbprintf(HWndDetails, "pWin32Mutex: %08X", ptdb->pWin32Mutex);
  550.         lbprintf(HWndDetails, "pSomeCritSect2: %08X", ptdb->pSomeCritSect2);
  551.         MBassert( !ptdb->un9 );
  552.         lbprintf(HWndDetails, "ripString: %08X", ptdb->ripString);
  553.     }
  554.  
  555.     SendMessage( HWndDetails, WM_SETREDRAW, TRUE, 0 );  // Turn on redraws
  556. }
  557.  
  558. void ShowTIBDetails( PTIB ptib )
  559. {
  560.     char szBuffer[384];
  561.  
  562.     #if 0   // Need a validation routine
  563.     if (.....
  564.     {
  565.         MessageBox( 0, "Not a valid TIB", 0, MB_OK );
  566.         return;
  567.     }
  568.     #endif
  569.         
  570.     wsprintf(szBuffer, "TIB: %08X", ptib );
  571.     SendMessage( HWndDetailsDescription, WM_SETTEXT, 0, (LPARAM)szBuffer );
  572.     SendMessage(HWndDetails, LB_RESETCONTENT, 0, 0);
  573.     
  574.     lbprintf(HWndDetails, "pvExcept: %08X", ptib->pvExcept);
  575.     lbprintf(HWndDetails, "pvStackUserTop: %08X", ptib->pvStackUserTop);
  576.     lbprintf(HWndDetails, "pvStackUserBase: %08X", ptib->pvStackUserBase);
  577.     lbprintf(HWndDetails, "pvTDB: %04X", ptib->pvTDB);
  578.     lbprintf(HWndDetails, "pvThunksSS: %04X", ptib->pvThunksSS);
  579.     lbprintf(HWndDetails, "SelmanList: %08X", ptib->SelmanList);
  580.     lbprintf(HWndDetails, "pvArbitrary: %08X", ptib->pvArbitrary);
  581.     lbprintf(HWndDetails, "ptibSelf: %08X", ptib->ptibSelf);
  582.     lbprintf(HWndDetails, "TIBFlags: %04X", ptib->TIBFlags);
  583.     lbprintf(HWndDetails, "Win16MutexCount: %04X", ptib->Win16MutexCount);
  584.     lbprintf(HWndDetails, "DebugContext: %08X", ptib->DebugContext);
  585.     lbprintf(HWndDetails, "pCurrentPriority: %08X", ptib->pCurrentPriority);
  586.     lbprintf(HWndDetails, "pvQueue: %04X", ptib->pvQueue);
  587.     lbprintf(HWndDetails, "pvTLSArray: %08X", ptib->pvTLSArray);
  588. }
  589.  
  590. void ShowModuleDetails( PIMTE pimte )
  591. {
  592.     char szBuffer[384];
  593.  
  594.     if ( !IsModule(pimte) )
  595.     {
  596.         MessageBox( 0, "Not a valid module", 0, MB_OK );
  597.         return;
  598.     }
  599.  
  600.     wsprintf(szBuffer, "Module: %08X", pimte);
  601.     SendMessage( HWndDetailsDescription, WM_SETTEXT, 0, (LPARAM)szBuffer );
  602.     SendMessage(HWndDetails, LB_RESETCONTENT, 0, 0);
  603.  
  604.     lbprintf( HWndDetails, "FileName: (%08X) %s", pimte->pszFileName, pimte->pszFileName );
  605.     lbprintf( HWndDetails, "FileName2: (%08X) %s", pimte->pszFileName2, pimte->pszFileName2 );
  606.     lbprintf( HWndDetails, "ModName: %s", pimte->pszModName );
  607.     lbprintf( HWndDetails, "ModName2: %s", pimte->pszModName2 );
  608.     lbprintf( HWndDetails, "cUsage: %04X", pimte->cUsage );
  609.     lbprintf( HWndDetails, "baseAddress: %08X", pimte->baseAddress );
  610.     lbprintf( HWndDetails, "cSections: %08X", pimte->cSections );
  611.     lbprintf( HWndDetails, "IMAGE_NT_HEADER: %08X", pimte->pNTHdr );
  612.     ShowPEHeader( pimte->pNTHdr );
  613.     
  614.     lbprintf( HWndDetails, "hModule16: %04X", pimte->hModule16 );
  615.     lbprintf( HWndDetails, "un1: %08X", pimte->un1 );
  616.     lbprintf( HWndDetails, "un3: %08X", pimte->un3 );
  617.     lbprintf( HWndDetails, "un5: %08X", pimte->un5 );
  618.     lbprintf( HWndDetails, "un7: %08X", pimte->un7 );
  619.  
  620.     // Uninteresting fields
  621.     // lbprintf( HWndDetails, "cbFileName: %04X", pimte->cbFileName );
  622.     // lbprintf( HWndDetails, "cbModName: %04X", pimte->cbModName );
  623.     // lbprintf( HWndDetails, "cbFileName: %04X", pimte->cbFileName );
  624.     
  625.     MBassert( pimte->un2 == -1 );
  626.  
  627. }
  628.  
  629. void ShowPEHeader( PIMAGE_NT_HEADERS pNTHdr )
  630. {
  631.     unsigned i;
  632.     PIMAGE_SECTION_HEADER pSection;
  633.     
  634.     pSection = IMAGE_FIRST_SECTION( pNTHdr );
  635.     
  636.     for ( i=1; i <= pNTHdr->FileHeader.NumberOfSections; i++ )
  637.     {
  638.         lbprintf(HWndDetails, "  %02X  %-8.8s  va:%08X  size:%08X",
  639.                 i, pSection->Name,
  640.                 pSection->VirtualAddress + pNTHdr->OptionalHeader.ImageBase,
  641.                 pSection->Misc.VirtualSize);
  642.                     
  643.         pSection++;
  644.     }
  645. }
  646.  
  647. void ShowMODREFListDetails( PMODREF pModRef )
  648. {
  649.     char szBuffer[384];
  650.  
  651.     if ( !IsMODREF(pModRef) )
  652.     {
  653.         MessageBox( 0, "Not a valid MODREF", 0, MB_OK );
  654.         return;
  655.     }
  656.  
  657.     InitModuleTableBase();      // In case PModuleTableArray got reallocated
  658.  
  659.     wsprintf( szBuffer, "MODREF list: %08X", pModRef );
  660.     SendMessage( HWndDetailsDescription, WM_SETTEXT, 0, (LPARAM)szBuffer );
  661.     SendMessage(HWndDetails, LB_RESETCONTENT, 0, 0);
  662.  
  663.     while ( pModRef )
  664.     {
  665.         GetModuleNameFromIMTEIndex( pModRef->mteIndex, szBuffer );
  666.         lbprintf( HWndDetails, "+%s", szBuffer );
  667.         RecordListboxLineTypeAndValue( HWndDetails, LB_ITEM_HMODULE, 
  668.                                       (DWORD)PModuleTable[pModRef->mteIndex] );
  669.         pModRef = pModRef->pNextModRef;
  670.     }
  671. }
  672.  
  673. void lbprintf(HWND hWnd, char * format, ...)
  674. {
  675.     char szBuffer[512];
  676.     va_list argptr;
  677.           
  678.     va_start(argptr, format);
  679.     wvsprintf(szBuffer, format, argptr);
  680.     va_end(argptr);
  681.  
  682.     SendMessage( hWnd, LB_ADDSTRING, 0, (LPARAM)szBuffer );
  683. }
  684.  
  685. typedef struct
  686. {
  687.     DWORD   type;
  688.     DWORD   value;
  689. } LBITEMDATA, *PLBITEMDATA;
  690.  
  691. // Records the type (module, process, etc...) of the line that was just
  692. // added to the specified listbox window, along with the value.
  693. void RecordListboxLineTypeAndValue(HWND hWnd, DWORD type, DWORD value)
  694. {
  695.     unsigned lastIndex;
  696.     PLBITEMDATA plbdata;
  697.     
  698.     lastIndex = SendMessage( hWnd, LB_GETCOUNT, 0, 0 );
  699.     if ( !lastIndex )
  700.         return;
  701.     
  702.     lastIndex--;    // Index is 0 based
  703.  
  704.     plbdata = malloc( sizeof(LBITEMDATA) );     // These will be freed in
  705.     if ( plbdata )                              // out WM_DELETEITEM handler
  706.     {                                           // in the dlg proc
  707.         plbdata->type = type;
  708.         plbdata->value = value;
  709.     }
  710.     
  711.     SendMessage( hWnd, LB_SETITEMDATA, lastIndex, (LPARAM)plbdata );
  712. }
  713.  
  714. BOOL RetrieveListboxLineTypeAndValue(HWND hWnd, DWORD *type, DWORD *value)
  715. {
  716.     PLBITEMDATA plbdata;
  717.     unsigned index = SendMessage( hWnd, LB_GETCURSEL, 0, 0 );
  718.  
  719.     plbdata = (PLBITEMDATA)SendMessage( hWnd, LB_GETITEMDATA, index, 0 );
  720.     if ( !plbdata || ((DWORD)plbdata == LB_ERR) )
  721.         return FALSE;
  722.  
  723.     *type = plbdata->type;
  724.     *value = plbdata->value;
  725.     
  726.     return TRUE;
  727. }
  728.  
  729. BOOL IsProcessId(DWORD pid)
  730. {
  731.     PPROCESS_DATABASE ppdb = PIDToPDB( pid );
  732.  
  733.     if ( (DWORD)ppdb < 0x80000000 )
  734.         return FALSE;
  735.     
  736.     if ( IsBadReadPtr((PVOID)ppdb, sizeof(DWORD)) )
  737.         return FALSE;
  738.  
  739.     if ( *(PDWORD)ppdb != 5 )
  740.         return FALSE;
  741.  
  742.     // There are additional sanity checks that can be made here
  743.  
  744.     return TRUE;
  745. }
  746.  
  747. BOOL IsThreadId(DWORD tid)
  748. {
  749.     PTHREAD_DATABASE ptdb = TIDToTDB( tid );
  750.         
  751.     if ( (DWORD)ptdb < 0x80000000 )
  752.         return FALSE;
  753.     
  754.     if ( IsBadReadPtr((PVOID)ptdb, sizeof(DWORD)) )
  755.         return FALSE;
  756.  
  757.     if ( *(PDWORD)ptdb != 6 )
  758.         return FALSE;
  759.  
  760.     // There are additional sanity checks that can be made here
  761.  
  762.     return TRUE;
  763. }
  764.  
  765. BOOL IsModule( PIMTE pimte )
  766. {
  767.     __try
  768.     {
  769.         // Verify there's a pointer to an IMAGE_NT_HEADER
  770.         if ( pimte->pNTHdr->Signature != IMAGE_NT_SIGNATURE )
  771.             return FALSE;
  772.  
  773.         // Verify that the number of sections that are stored in two
  774.         // places match up.
  775.         if ( pimte->pNTHdr->FileHeader.NumberOfSections != pimte->cSections )
  776.             return FALSE;
  777.  
  778.         // Verify the pointers to the EXE/module names
  779.         if ( IsBadReadPtr( pimte->pszFileName, 1) )
  780.             return FALSE;
  781.         if ( IsBadReadPtr( pimte->pszModName, 1) )
  782.             return FALSE;
  783.         if ( pimte->pszFileName > pimte->pszModName )
  784.             return FALSE;
  785.     }
  786.     __except( 1 )
  787.     {
  788.         return FALSE;
  789.     }
  790.     
  791.     return TRUE;
  792. }
  793.  
  794. BOOL IsMODREF( PMODREF pModRef )
  795. {
  796.     if ( (DWORD)pModRef < 0x80000000 )
  797.         return FALSE;
  798.     
  799.     if ( IsBadReadPtr( pModRef, sizeof(MODREF) ) )
  800.         return FALSE;
  801.             
  802.     if ( pModRef->pNextModRef != 0 )
  803.     {
  804.         if ( (DWORD)pModRef->pNextModRef < 0x80000000 )
  805.             return FALSE;
  806.  
  807.         if ( IsBadReadPtr(pModRef->pNextModRef, sizeof(MODREF)) )
  808.             return FALSE;
  809.     }
  810.  
  811.     return TRUE;
  812. }
  813.  
  814. PPROCESS_DATABASE PIDToPDB( DWORD pid )
  815. {
  816.     return (PPROCESS_DATABASE)(pid ^ Unobsfucator);
  817. }
  818.  
  819. PTHREAD_DATABASE TIDToTDB( DWORD tid )
  820. {
  821.     return (PTHREAD_DATABASE)(tid ^ Unobsfucator);
  822. }
  823.  
  824. void GetProcessNameFromHTask( HTASK hTask, PSTR pszBuffer )
  825. {
  826.     pszBuffer[0] = 0;
  827.     
  828.     __try
  829.     {
  830.         __asm
  831.         {
  832.             push ds
  833.             push ds
  834.             pop  es
  835.             mov ds, word ptr [hTask]
  836.             mov esi, 0F2h
  837.             mov edi, [pszBuffer]
  838.             mov ecx, 2
  839.             cld
  840.             rep movsd
  841.             mov byte ptr es:[edi], 0
  842.             pop ds
  843.         }
  844.     }
  845.     __except( 1 ){}
  846.     
  847. }
  848.  
  849. void InitUnobsfucator(void)
  850. {
  851.     DWORD   tid;
  852.     
  853.     tid = GetCurrentThreadId();
  854.     
  855.     __asm {
  856.             mov     ax, fs
  857.             mov     es, ax
  858.             mov     eax, 18h
  859.             mov     eax, es:[eax]
  860.             sub     eax, 10h
  861.             xor     eax,[tid]
  862.             mov     [Unobsfucator], eax
  863.     }
  864. }
  865.  
  866. void WINAPI GDIReallyCares( HINSTANCE );
  867.  
  868. void InitModuleTableBase(void)
  869. {
  870.     // Yes, this is really disgusting!
  871.     GDIReallyCares( GetModuleHandle(0) );
  872.     __asm   mov     [PModuleTable], ecx
  873. }
  874.  
  875. void InitKernel32HeapHandle(void)
  876. {
  877.     PPROCESS_DATABASE ppdb;
  878.  
  879.     ppdb = PIDToPDB( GetCurrentProcessId() );
  880.     
  881.     HKernel32Heap = ppdb->HeapHandle;
  882. }
  883.  
  884. //
  885. // Dialog proc for the main dialog
  886. //
  887. BOOL CALLBACK Win32WlkDlgProc(HWND hWndDlg, UINT msg,
  888.                               WPARAM wParam, LPARAM lParam)
  889. {
  890.     switch ( msg )
  891.     {
  892.         case WM_COMMAND:
  893.             Handle_WM_COMMAND(hWndDlg, wParam, lParam); return TRUE;
  894.         case WM_INITDIALOG:
  895.             Handle_WM_INITDIALOG(hWndDlg); return TRUE;
  896.         case WM_CLOSE:
  897.             EndDialog(hWndDlg, 0); return FALSE;
  898.         case WM_DELETEITEM:
  899.             Handle_WM_DELETEITEM( hWndDlg, wParam, lParam ); return TRUE;
  900.     }
  901.     return FALSE;
  902. }
  903.  
  904. //
  905. // Handle the dialog's WM_COMMAND messages
  906. //
  907. void Handle_WM_COMMAND(HWND hWndDlg, WPARAM wParam, LPARAM lParam)
  908. {
  909.     //
  910.     // If user hit <enter> see which listbox has the focus, and
  911.     // change wParam and lParam to look as if the user performed
  912.     // the equivalent dbl-click action.
  913.     //
  914.     if ( LOWORD(wParam) == IDOK )
  915.     {
  916.         HWND hWndFocus = GetFocus();
  917.         if (hWndFocus == HWndDetails )
  918.         {
  919.             wParam = IDC_LB_DETAILS; lParam = MAKELONG(0,LBN_DBLCLK);
  920.         }
  921.     }
  922.     
  923.     switch ( LOWORD(wParam) )
  924.     {
  925.         case IDC_RB_PROCESSES:
  926.             UpdateProcessList();
  927.             break;
  928.             
  929.         case IDC_RB_THREADS:
  930.             UpdateThreadList();
  931.             break;
  932.             
  933.         case IDC_RB_MODULES:
  934.             UpdateModuleList();
  935.             break;
  936.             
  937.         case IDC_LB_MAIN_LIST:
  938.             if ( HIWORD(wParam) == LBN_SELCHANGE )
  939.             {
  940.                 DWORD handle, type;
  941.                 DWORD lbSelectedIndex;
  942.                 
  943.                 lbSelectedIndex = SendMessage(HWndMainList,LB_GETCURSEL, 0, 0);
  944.                 RetrieveListboxLineTypeAndValue(HWndMainList, &type, &handle);
  945.                                     
  946.                 if ( IsDlgButtonChecked(hWndDlg, IDC_RB_PROCESSES) )
  947.                     ShowProcessDetails( handle );
  948.                 else if ( IsDlgButtonChecked(hWndDlg, IDC_RB_THREADS) )
  949.                     ShowThreadDetails( handle );
  950.                 else
  951.                     ShowModuleDetails( (HMODULE)handle );
  952.             }
  953.             break;
  954.             
  955.         case IDC_LB_DETAILS:
  956.             if ( HIWORD(wParam) == LBN_DBLCLK )
  957.             {
  958.                 DWORD type, value;
  959.                 
  960.                 if ( !RetrieveListboxLineTypeAndValue(HWndDetails,
  961.                                                         &type, &value) )
  962.                     break;
  963.                 
  964.                 switch ( type )
  965.                 {
  966.                     case LB_ITEM_HMODULE:
  967.                         ShowModuleDetails( (PIMTE)value ); break;
  968.                     case LB_ITEM_PROCESS:
  969.                         ShowProcessDetails( value ); break;
  970.                     case LB_ITEM_MODREF_LIST:
  971.                         ShowMODREFListDetails( (PMODREF)value ); break;
  972.                     case LB_ITEM_HANDLE_TABLE:
  973.                         ShowHandleTableDetails( (PHANDLE_TABLE)value ); break;
  974.                     case LB_ITEM_TIB:
  975.                         ShowTIBDetails( (PTIB)value ); break;
  976.                 }
  977.             }
  978.             break;
  979.     }
  980.     return;
  981. }
  982.  
  983. void Handle_WM_INITDIALOG(HWND hWndDlg)
  984. {
  985.     HWndMainList = GetDlgItem(hWndDlg, IDC_LB_MAIN_LIST);
  986.     HWndDetails = GetDlgItem(hWndDlg, IDC_LB_DETAILS);
  987.     HWndDetailsDescription = GetDlgItem(hWndDlg, IDC_DETAILS_TYPE );
  988.  
  989.     fDebugVersion = (BOOL)GetSystemMetrics( SM_DEBUG );
  990.  
  991.     InitUnobsfucator();
  992.     InitModuleTableBase();
  993.     InitKernel32HeapHandle();
  994.     
  995.     CheckDlgButton(hWndDlg, IDC_RB_PROCESSES, 1);
  996.     
  997.     if ( IsDlgButtonChecked(hWndDlg, IDC_RB_PROCESSES) )
  998.         UpdateProcessList();   
  999. }
  1000.  
  1001. void Handle_WM_DELETEITEM(HWND hWndDlg, WPARAM wParam, LPARAM lParam)
  1002. {
  1003.     if ( wParam != IDC_LB_DETAILS )
  1004.         return;
  1005.     
  1006.     // Free the pointer stored in the item data
  1007.     free( (PVOID)((LPDELETEITEMSTRUCT)lParam)->itemData );
  1008. }
  1009.  
  1010. void GetModuleNameFromIMTEIndex( unsigned short index, PSTR pszBuffer )
  1011. {
  1012.     lstrcpy( pszBuffer, PModuleTable[index]->pszModName );
  1013. }
  1014.  
  1015. PSTR GetKernel32ObjectType( PVOID pObject )
  1016. {
  1017.     if ( IsBadReadPtr(pObject, 4) )
  1018.         return "<???>";
  1019.     
  1020.     switch( *(PDWORD)pObject )
  1021.     {
  1022.         case K32OBJ_SEMAPHORE: return "SEMAPHORE";
  1023.         case K32OBJ_EVENT: return "EVENT";
  1024.         case K32OBJ_MUTEX: return "MUTEX";
  1025.         case K32OBJ_CRITICAL_SECTION: return "CRITICAL_SECTION";
  1026.         case K32OBJ_PROCESS: return "PROCESS";
  1027.         case K32OBJ_THREAD: return "THREAD";
  1028.         case K32OBJ_FILE: return "FILE";
  1029.         case K32OBJ_CHANGE: return "CHANGE";
  1030.         case K32OBJ_CONSOLE: return "CONSOLE";
  1031.         case K32OBJ_SCREEN_BUFFER: return "SCREEN_BUFFER";
  1032.         case K32OBJ_MEM_MAPPED_FILE: return "MEM_MAPPED_FILE";
  1033.         case K32OBJ_SERIAL: return "SERIAL";
  1034.         case K32OBJ_DEVICE_IOCTL: return "DEVICE_IOCTL";
  1035.         case K32OBJ_PIPE: return "PIPE";
  1036.         case K32OBJ_MAILSLOT: return "MAILSLOT";
  1037.         case K32OBJ_TOOLHELP_SNAPSHOT: return "TOOLHELP_SNAPSHOT";
  1038.         case K32OBJ_SOCKET: return "SOCKET";
  1039.         default: return "<unknown>";
  1040.     }
  1041. }
  1042.  
  1043. // Our own custom assert for GUI programs
  1044. void __cdecl _MBassert(void *pszExp, void *pszFile, unsigned lineNum)
  1045. {
  1046.     char buffer[512];
  1047.     
  1048.     wsprintf(buffer, "assert: %s (%s line %u)", pszExp, pszFile, lineNum);
  1049.     MessageBox( 0, buffer, 0, MB_OK );
  1050. }
  1051.